<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>二进制数据类型</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="datatype-character.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="datatype.html">快退</a></td><td width="60%" align="center" valign="bottom">章8. Data Types</td><td width="10%" align="right" valign="top"><a href="datatype.html">快进</a></td><td width="10%" align="right" valign="top"><a href="datatype-datetime.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="DATATYPE-BINARY">8.4. 二进制数据类型</a></h1><a name="AEN4364"></a><a name="AEN4366"></a>
<p><tt class="TYPE">bytea</tt> 数据类型允许存储二进制字符串。参阅<a href="datatype-binary.html#DATATYPE-BINARY-TABLE">表8-6</a>。</p>
<div class="TABLE"><a name="DATATYPE-BINARY-TABLE"></a>
<p><b>表8-6. 二进制数据类型</b></p>
<table border="1" class="CALSTABLE"><col><col><col>
<thead>
<tr><th>名字</th><th>存储空间</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><tt class="TYPE">bytea</tt></td><td>4 字节加上实际的二进制字符串</td><td>变长的二进制字符串</td></tr>
</tbody>
</table>
</div>
<p>二进制字符串是一个字节序列。二进制字符串和普通字符字符串的区别有两个：首先，二进制字符串完全可以存储字节零值以及其它"不可打印的"字节(定义在 32 到 126 范围之外的字节)。字符串不允许字节零值，并且也不允许那些不附合选定的字符集编码的非法字节值或者字节序列。第二，对二进制字符串的处理实际上就是处理字节，而对字符串的处理则取决于区域设置。简单说，二进制字符串适用于存储那些程序员认为是"原始字节"的数据，而字符串适合存储文本。</p>
<p>在一个 SQL 语句的文本串里面输入 <tt class="TYPE">bytea</tt> 数值的时候，你<span class="emphasis"><i class="EMPHASIS">必须</i></span>逃逸某些字节值(但<span class="emphasis"><i class="EMPHASIS">可以</i></span>逃逸所有字节值)。通常，要逃逸一个字节值，需要把它的数值转换成对应的三位八进制数，并且前导两个反斜杠。有些八进制数值有可选的逃逸序列，在<a href="datatype-binary.html#DATATYPE-BINARY-SQLESC">表8-7</a>中显示，同时也给出了可选的逃逸序列。</p>
<div class="TABLE"><a name="DATATYPE-BINARY-SQLESC"></a>
<p><b>表8-7. <tt class="TYPE">bytea</tt> 文本逃逸八进制</b></p>
<table border="1" class="CALSTABLE"><col><col><col><col><col>
<thead>
<tr><th>十进制数值</th><th>描述</th><th>输入逃逸形式</th><th>例子</th><th>输出形式</th></tr>
</thead>
<tbody>
<tr><td>0</td><td>八进制的零</td><td><tt class="LITERAL">E'\\000'</tt></td><td><tt class="LITERAL">SELECT E'\\000'::bytea;</tt></td><td><tt class="LITERAL">\000</tt></td></tr>
<tr><td>39</td><td>单引号</td><td><tt class="LITERAL">''''</tt> 或 <tt class="LITERAL">E'\\047'</tt></td><td><tt class="LITERAL">SELECT E'\''::bytea;</tt></td><td><tt class="LITERAL">'</tt></td></tr>
<tr><td>92</td><td>反斜杠</td><td><tt class="LITERAL">E'\\\\'</tt> 或 <tt class="LITERAL">E'\\134'</tt></td><td><tt class="LITERAL">SELECT E'\\\\'::bytea;</tt></td><td><tt class="LITERAL">\\</tt></td></tr>
<tr><td>0 到 31 以及 127 到 255</td><td>"不可打印"字节</td><td><tt class="LITERAL">E'\\<tt class="REPLACEABLE"><i>xxx'</i></tt></tt>(八进制值)</td><td><tt class="LITERAL">SELECT E'\\001'::bytea;</tt></td><td><tt class="LITERAL">\001</tt></td></tr>
</tbody>
</table>
</div>
<p>逃逸"不可打印"字节的要求因区域设置而异。在某些场合下，你可以不逃逸它们。请注意<a href="datatype-binary.html#DATATYPE-BINARY-SQLESC">表8-7</a>里的每个例子都是刚好一个字节长，虽然字节零和反斜杠输出形式比一个字符要长。</p>
<p>你必须写这么多反斜杠的原因，如<a href="datatype-binary.html#DATATYPE-BINARY-SQLESC">表8-7</a>所示，是因为一个写成字符串文本的输入字符串必须通过 PostgreSQL 服务器里的两个分析阶段。每一对反斜杠中的第一个会被字符串文本分析器理解成一个逃逸字符而消耗掉，于是剩下的第二个反斜杠被 <tt class="TYPE">bytea</tt> 输入函数当作一个三位八进制值或者是逃逸另外一个反斜杠的开始。比如，一个传递给服务器的字符串文本 <tt class="LITERAL">E'\\001'</tt> 在通过字符串分析器之后会当作 <tt class="LITERAL">\001</tt> 发送给 <tt class="TYPE">bytea</tt> 输入函数，在这里它被转换成一个十进制值为 1 的单个字节。请注意，单引号字符(<tt class="LITERAL">'</tt>)不会被 <tt class="TYPE">bytea</tt> 特殊对待，它遵循字符串文本的普通规则。又见<a href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">节4.1.2.1</a>。</p>
<p><tt class="TYPE">bytea</tt> 字节也在输出中逃逸。通常，每个"不可打印"的字节值都转化成对应的前导反斜杠的三位八进制数值。大多数"可打印的"字节值是以客户端字符集的标准表现形式出现的。十进制值为 92(反斜杠)的字节有一个特殊的可选输出形式。细节在<a href="datatype-binary.html#DATATYPE-BINARY-RESESC">表8-8</a>里描述。</p>
<div class="TABLE"><a name="DATATYPE-BINARY-RESESC"></a>
<p><b>表8-8. <tt class="TYPE">bytea</tt> 输出逃逸序列</b></p>
<table border="1" class="CALSTABLE"><col><col><col><col><col>
<thead>
<tr><th>字节的十进制值</th><th>描述</th><th>逃逸的输出形式</th><th>例子</th><th>输出结果</th></tr>
</thead>
<tbody>
<tr><td>92</td><td>反斜杠</td><td><tt class="LITERAL">\\</tt></td><td><tt class="LITERAL">SELECT E'\\134'::bytea;</tt></td><td><tt class="LITERAL">\\</tt></td></tr>
<tr><td>0 到 31 以及 127 到 255</td><td>"不可打印"八进制字符</td><td><tt class="LITERAL">\<tt class="REPLACEABLE"><i>xxx</i></tt></tt>(八进制值)</td><td><tt class="LITERAL">SELECT E'\\001'::bytea;</tt></td><td><tt class="LITERAL">\001</tt></td></tr>
<tr><td>32 到 126</td><td>"可打印"八进制字符</td><td>客户端字符集表现形式</td><td><tt class="LITERAL">SELECT E'\\176'::bytea;</tt></td><td><tt class="LITERAL">~</tt></td></tr>
</tbody>
</table>
</div>
<p>根据你使用的前端不同，在是否逃逸 <tt class="TYPE">bytea</tt> 字符串的问题上你可能有一些额外的工作要做。比如，如果你的接口自动转换换行和回车，那你可能还要逃逸它们。</p>
<p>SQL 标准定义了一种不同的二进制字符串类型，叫做 <tt class="TYPE">BLOB</tt> 或 <tt class="TYPE">BINARY LARGE OBJECT</tt> 。其输入格式和 <tt class="TYPE">bytea</tt> 不同，但是提供的函数和操作符大多一样。</p>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="datatype-character.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="datatype-datetime.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">字符类型</td><td width="34%" align="center" valign="top"><a href="datatype.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">日期/时间类型</td></tr>
</table>
</div>
</body></html>